import { useContext, useEffect, useState } from 'react'
import ProcessEditorContext from '../context'
import { Tree } from 'antd'
import FLOWABLE from '../FLOWABLE'

const ProcessTree = () => {

  const {
    editorManager
  } = useContext(ProcessEditorContext)

  const [treeData, setTreeData] = useState([])
  const [selectedKeys, setSelectedKeys] = useState([])
  const [openedKeys, setOpenedkeys] = useState([])
  const [treeLoaded, setTreeLoaded] = useState(false)

  const renderTree = () => {
    if (!editorManager.isLoading()) {
      function getTreeData(arr) {
        return arr.map(el => {
          const hasChild = el.children && el.children.length
          if (hasChild) {
            _openedKeys.push(el.id)
          }
          if (el.current) {
            _selectedKeys = [el.id]
          }
          return {
            ...el,
            key: el.id,
            title: el.name,
            disabled: el.type === 'SubProcess',
            children: hasChild ? getTreeData(el.children) : []
          }
        })
      }
      const _treeData = editorManager.getTree()
      let _selectedKeys = []
      let _openedKeys = []
      setTreeData(getTreeData([_treeData]))
      setOpenedkeys(_openedKeys)
      setSelectedKeys(_selectedKeys)
      setTreeLoaded(true)
    }
  }

  function filterEvent(event) {
    //this event is fired when the user changes a property by the property editor.
    if (event.type === "event-type-property-value-changed") {
      if (event.property.key === "oryx-overrideid" || event.property.key === "oryx-name") {
        renderTree()
      }
      //this event is fired when the stencil / shape's text is changed / updated.
    } else if (event.type === "propertyChanged") {
      if (event.name === "oryx-overrideid" || event.name === "oryx-name") {
        renderTree();
      }
    } else if (event.type === ORYX.CONFIG.ACTION_DELETE_COMPLETED) {
      renderTree();
      //for some reason the new tree does not trigger an ui update.
      //$scope.$apply();
    } else if (event.type === "event-type-item-dropped") {
      renderTree();
    }
  }

  useEffect(() => {
    renderTree();
    editorManager.registerOnEvent(ORYX.CONFIG.ACTION_DELETE_COMPLETED, filterEvent);
    editorManager.registerOnEvent(ORYX.CONFIG.EVENT_UNDO_ROLLBACK, renderTree);
    FLOWABLE.eventBus.addListener("EDITORMANAGER-EDIT-ACTION", renderTree);
    FLOWABLE.eventBus.addListener(FLOWABLE.eventBus.EVENT_TYPE_ITEM_DROPPED, filterEvent);
    FLOWABLE.eventBus.addListener(FLOWABLE.eventBus.EVENT_TYPE_PROPERTY_VALUE_CHANGED, filterEvent);
    return () => {
      editorManager.unregisterOnEvent(ORYX.CONFIG.ACTION_DELETE_COMPLETED, filterEvent);
      editorManager.unregisterOnEvent(ORYX.CONFIG.EVENT_UNDO_ROLLBACK, renderTree);
      FLOWABLE.eventBus.removeListener("EDITORMANAGER-EDIT-ACTION", renderTree)
      FLOWABLE.eventBus.removeListener(FLOWABLE.eventBus.EVENT_TYPE_ITEM_DROPPED, filterEvent);
      FLOWABLE.eventBus.removeListener(FLOWABLE.eventBus.EVENT_TYPE_PROPERTY_VALUE_CHANGED, filterEvent);
    }
  }, [])


  const renderTreeNode = (arr) => {
    return arr.map(el => {
      const hasChild = el.children && el.children.length > 0
      return <TreeNode key={el.id} title={el.name} >
        {
          hasChild && renderTreeNode(el.children)
        }
      </TreeNode>
    })
  }

  const handleSelect = (selectedKeys, { node }) => {
    // setSelectedKeys(selectedKeys);
    editorManager.edit(node.id);
  }

  return <div className="p-d-tree-box">
    {
      treeLoaded && <Tree
        defaultExpandAll
        blockNode
        showLine
        showLeafIcon
        treeData={treeData}
        // expandedKeys={openedKeys}
        selectedKeys={selectedKeys}
        onSelect={handleSelect}
      ></Tree>
    }
  </div>
}

export default ProcessTree